package com.gitee.feizns.quickstart.validation.validator;

import com.gitee.feizns.dynamic.Objs;

import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

/**
 * 验证元素T数组{@link Array}或者集合{@link Collection}中是否都匹配对应的序列
 * @author feizns
 * @since 2023/2/7
 */
public abstract class AbstractAllMatchConstraintValidator<A extends Annotation, T> extends AbstractConstraintValidator<A, T> {

    /**
     * 值列表
     */
    private Set<T> values;

    /**
     * 初始化所以值
     * @return {@link Collection}
     */
    protected abstract Set<T> initializeValues(A constraintAnnotation);

    @Override
    public void initialize(A constraintAnnotation) {
        super.initialize(constraintAnnotation);
        this.values = initializeValues(constraintAnnotation);
    }

    @Override
    public boolean isValid(T value, ConstraintValidatorContext context) {
        if ( value != null ) {
            if ( Objs.isArray(value) )
                return Arrays.stream(Objs.toArray(value)).allMatch(this::contains);
            else if ( value instanceof Collection )
                return ((Collection<?>) value).stream().allMatch(this::contains);
            return contains(value);
        }
        return true;
    }

    /**
     * 是否包含对应的值
     * @param value 值
     * @return 是否包含
     */
    @SuppressWarnings("unchecked")
    public boolean contains(Object value) {
        return values.contains((T) value);
    }

}
